from django.shortcuts import render
from rest_framework import viewsets, filters, status
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework.permissions import AllowAny
from django_filters.rest_framework import DjangoFilterBackend
from django.utils import timezone
from .models import Task, Category, Tag
from .serializers import TaskSerializer, CategorySerializer, TagSerializer
from django.contrib.auth import get_user_model

User = get_user_model()

# Create your views here.

class CategoryViewSet(viewsets.ModelViewSet):
    """
    分类视图集
    提供分类的CRUD操作
    
    支持的HTTP方法：
    - GET /api/categories/ - 获取所有分类
    - POST /api/categories/ - 创建新分类
    - GET /api/categories/{id}/ - 获取单个分类
    - PUT /api/categories/{id}/ - 更新分类
    - PATCH /api/categories/{id}/ - 部分更新分类
    - DELETE /api/categories/{id}/ - 删除分类
    """
    queryset = Category.objects.all()
    serializer_class = CategorySerializer
    permission_classes = [AllowAny]

class TagViewSet(viewsets.ModelViewSet):
    """
    标签视图集
    提供标签的CRUD操作
    
    支持的HTTP方法：
    - GET /api/tags/ - 获取所有标签
    - POST /api/tags/ - 创建新标签
    - GET /api/tags/{id}/ - 获取单个标签
    - PUT /api/tags/{id}/ - 更新标签
    - PATCH /api/tags/{id}/ - 部分更新标签
    - DELETE /api/tags/{id}/ - 删除标签
    """
    queryset = Tag.objects.all()
    serializer_class = TagSerializer
    permission_classes = [AllowAny]

class TaskViewSet(viewsets.ModelViewSet):
    """
    任务视图集
    提供任务的CRUD操作和自定义操作
    
    支持的HTTP方法：
    - GET /api/tasks/ - 获取所有任务
    - POST /api/tasks/ - 创建新任务
    - GET /api/tasks/{id}/ - 获取单个任务
    - PUT /api/tasks/{id}/ - 更新任务
    - PATCH /api/tasks/{id}/ - 部分更新任务
    - DELETE /api/tasks/{id}/ - 删除任务
    
    自定义操作：
    - POST /api/tasks/{id}/complete/ - 标记任务为已完成
    - GET /api/tasks/overdue/ - 获取所有过期任务
    - GET /api/tasks/priority/{priority}/ - 按优先级获取任务
    - GET /api/tasks/category/{category_id}/ - 按分类获取任务
    - GET /api/tasks/tag/{tag_id}/ - 按标签获取任务
    """
    #定义了视图集默认操作的数据范围，如果没有重写get_queryset方法，DRF会直接使用这个固定的queryset
    queryset = Task.objects.all()
    #序列化器作用：实现python对象和json数据之间进行转换
    serializer_class = TaskSerializer#这个属性用来指定当前视图集所使用的序列化器
    permission_classes = [AllowAny]#指明了哪些用户可以访问这个视图集
    filter_backends = [DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]#定义了视图集支持的过滤、搜索、排序功能
    filterset_fields = ['status', 'priority', 'category', 'tags']#基于字段的过滤功能
    search_fields = ['title', 'description']#基于字段的模糊匹配功能
    ordering_fields = ['created_at', 'due_date', 'priority']#基于字段的排序功能

    #实现了基于用户身份的数据过滤
    def get_queryset(self):
        #self.request.user:获取当前请求的用户
        #如果用户登陆了，返回该用户的任务
        if self.request.user.is_authenticated:
            return Task.objects.filter(created_by=self.request.user)
        #如果用户没有登陆，返回所有任务
        return Task.objects.all()

    #detail=true:表示这个动作作用于单个对象，如果针对单个对象，那么需要传入pk参数
    @action(detail=True, methods=['post'])
    def complete(self, request, pk=None):
        """
        标记任务为已完成
        请求方法：POST
        请求路径：/api/tasks/{id}/complete/
        
        响应：
        - 200 OK: 任务成功标记为已完成
        - 404 Not Found: 任务不存在
        """
        task = self.get_object()# 内置方法，用来根据url中的pk获取模型实例
        task.status = 'C'
        task.completed_at = timezone.now()
        task.save()
        return Response({'status': '任务已完成'})

    @action(detail=True, methods=['post'])
    def uncomplete(self, request, pk=None):
        task = self.get_object()
        task.status = 'P'
        task.completed_at = None
        task.save()
        return Response({'status': 'task uncompleted'})

    @action(detail=False, methods=['get'])
    def overdue(self, request):
        """
        获取所有过期任务
        请求方法：GET
        请求路径：/api/tasks/overdue/
        
        响应：
        - 200 OK: 返回所有过期任务列表
        """
        overdue_tasks = Task.objects.filter(
            due_date__lt=timezone.now(),
            status__in=['P', 'I']
        )#查询集，可以理解为查询结果，是一个个的python对象
        # 将python对象转换为字典，使用serializer获取json格式的数据
        serializer = self.get_serializer(overdue_tasks, many=True)#获取当前视图集对应的序列化器；many=True表示返回的是一个列表
        return Response(serializer.data)

    # ?P<priority>：定义了一个名为 priority 的参数。
    # [^/.]+：匹配任意非斜杠字符（至少一个字符），表示优先级值。
    @action(detail=False, methods=['get'], url_path='priority/(?P<priority>[^/.]+)')
    def by_priority(self, request, priority=None):
        """
        按优先级获取任务
        请求方法：GET
        请求路径：/api/tasks/priority/{priority}/
        
        参数：
        - priority: 优先级值（L/M/H）
        
        响应：
        - 200 OK: 返回指定优先级的任务列表
        - 400 Bad Request: 优先级值无效
        """
        if priority not in ['L', 'M', 'H']:
            return Response(
                {'error': '无效的优先级值'},
                status=status.HTTP_400_BAD_REQUEST
            )
        tasks = Task.objects.filter(priority=priority)
        serializer = self.get_serializer(tasks, many=True)
        return Response(serializer.data)

    @action(detail=False, methods=['get'], url_path='category/(?P<category_id>[^/.]+)')
    def by_category(self, request, category_id=None):
        """
        按分类获取任务
        请求方法：GET
        请求路径：/api/tasks/category/{category_id}/
        
        参数：
        - category_id: 分类ID
        
        响应：
        - 200 OK: 返回指定分类的任务列表
        - 404 Not Found: 分类不存在
        """
        try:
            tasks = Task.objects.filter(category_id=category_id)
            serializer = self.get_serializer(tasks, many=True)
            return Response(serializer.data)
        except Category.DoesNotExist:
            return Response(
                {'error': '分类不存在'},
                status=status.HTTP_404_NOT_FOUND
            )

    @action(detail=False, methods=['get'], url_path='tag/(?P<tag_id>[^/.]+)')
    def by_tag(self, request, tag_id=None):
        """
        按标签获取任务
        请求方法：GET
        请求路径：/api/tasks/tag/{tag_id}/
        
        参数：
        - tag_id: 标签ID
        
        响应：
        - 200 OK: 返回指定标签的任务列表
        - 404 Not Found: 标签不存在
        """
        try:
            tasks = Task.objects.filter(tags__id=tag_id)
            serializer = self.get_serializer(tasks, many=True)
            return Response(serializer.data)
        #尝试根据tag_id查询标签的时候，如果没找到就会抛出Tag.DoesNotExist异常，这是django内置的异常类
        except Tag.DoesNotExist:
            return Response(
                {'error': '标签不存在'},
                status=status.HTTP_404_NOT_FOUND
            )

    def perform_create(self, serializer):
        # 保存时会自动将request传递给序列化器
        serializer.save()
